function JEnumPicker(owner, parent, name, dataset, field, rect, tab, tabStop, tabIndex)
{
	var self = this,
		_disposed = false,
		_itemsCount = 0,
		_form = null;

	this.initialize (owner, parent, name, null, null, rect, null, field, dataset, tab)

	this.dataset  = dataset;
	this.field    = field;
	this.rolled   = isRolled;
	this.value    = null;
	this.methods  = (cmRender | cmLoad | cmSave);
	this.dirty    = false;
	this.orgValue = null;
	this.inplace  = false;
	this.tabStop  = tabStop;
	this.tabIndex = (tabIndex == null) ? -1 : parseInt(tabIndex);
	
	this.owner.addImage("drop-down", "drop-down.gif", "controls");
	
	// events
	this.onchange = new JEvent();
	this.onrolling = new JEvent();

	// public methods
	this.canRollQuery   = null;
	this.render			= render;
	this.load			= load;
	this.save			= save;
	this.select			= select;
	this.keyHandler		= keyHandler;
	this.refreshPicker	= refreshPicker; 
	this.roll			= roll;
	this.isReadOnly		= isReadOnly;
	this.dispose		= dispose;

	this.bind_setValue = bind_setValue;

	function isReadOnly(dataset, field)
	{
		return dataset.isReadOnly(field) && (self.name.indexOf("pgsel") == -1);
	}
	
	function render(fs)
	{
		var localFs = false;
		if (!fs)
		{
			fs = new FastString();
			localFs = true;
		}

		var addClass = '';

		if (self.isInvisible())
		{
			addClass += ' invisible';
		}
	  
		fs.append('<nobr><input class="enumpicker' + addClass + '" type="text" id="' + self.name + '" />');

		//if (!readOnly)
		{
			fs.append('<img class="enumpickerImg' + addClass + '" id="' + self.name + '_img" src="' + self.owner.images["drop-down"].src + '" />');
		}

		fs.append('<div class="picker' + addClass + '" id="' + self.name + '_picker">');
		if (! self.isInvisible())
			_refreshPickerItems(fs);
		fs.append("</div></nobr>");

		if (localFs)
			return (fs.toString());
	}
	
	function load()
	{
		var //readOnly = self.isReadOnly(self.dataset, self.field),
			elem = self.$$(),
			picker = self.$$("_picker"),
			style = elem.style,
			img = self.$$('_img'),
			imgStyle = null,
			corr = 0;

		if (img != null)
		  imgStyle = img.style;

		elem.tabIndex = self.tabIndex;

		elem.value = self.dataset.getText(self.field);
		self.value = self.dataset.get(self.field);
		
		elem.onkeydown = self.keyHandler;
		_form = self.getForm();
		if ((_form != null) && (_form.setActiveControl))
			elem.onfocus = function() {_form.setActiveControl(self); };

		//if (! readOnly)
		{
			img.onclick = self.roll;
			corr = 17;
		}

		var doc = self.owner.getDocument();
		doc.body.appendChild(picker);	// move it to body so that it may overlap other elements

		if (self.inplace)
		{
			var prnt = elem.parentNode.parentNode;
			var pos = utils.getElementBox(prnt, doc);

			elem.className = 'editInplace';
			if (img != null)
				img.className = 'enumpickerImgInplace';

			if (pos.height != 0)
			{
				style.height = pos.height - 2;
				style.fontSize = pos.height - 8;
			}
			if (pos.width != 0)
				style.width = pos.width - corr - 4;

			style.textAlign = prnt.style.textAlign;
			prnt.style.textAlign = '';

		}
		else
		if (self.rect.isRelative())
		{
			if (img != null)
				img.className = 'enumpickerImgRelative';
			elem.className = 'enumpicker enumpickerRelative';

			style.height = self.rect.height;
			style.width = self.rect.width; // - corr;
		}
		else
		{
			style.position = 'absolute';
			style.top = self.rect.top;
			style.left = self.rect.left;
			style.height = self.rect.height;
			style.width = self.rect.width - corr;

			if (imgStyle != null)
			{
				imgStyle.position = 'absolute';
				imgStyle.left = self.rect.left + self.rect.width - corr;
				imgStyle.top = self.rect.top + 2;
				imgStyle.height = self.rect.height - 4;
			}
		}

/*
		if (readOnly)
		{
			elem.readOnly = true;
			elem.className += ' readOnly';
		}
		else
*/

		checkControlState();

		_setClickHandlers();

		if (self.value != null)
			self.select(self.value);
		self.orgValue = self.value;

		if (!self.field.startsWith('__'))
			dataset.bindingManager.bind(self, '', self.field);
	}

	function getClickFunc(idx)
	{
		return function() { self.select(idx); };
	}

	function checkControlState(record)
	{
		if ((!record) && (! self.field.startsWith('__')))
			record = self.dataset.getCurrentRecord();
		
		var elem = self.$$(),
		    style = elem.style,
			img = self.$$('_img');

		elem.readOnly = true;

		var corr = 0;

		if ((record) && (record.isReadOnly(self.field)))
		{
			elem.className += ' readOnly';
			
			if (img)
				img.style.display = 'none';
		}
		else
		{
			elem.className = elem.className.replace(' readOnly', '');

			if (img)
			{
				img.style.display = '';
				corr = 17;
			}
		}

		var required = (record) && (record.isRequired(self.field));
		if (required)
		{
			if (elem.className.indexOf('requiredField') == -1)
				elem.className += ' requiredField';
		}
		else
			elem.className = elem.className.replace(' requiredField', '');


		var doc = self.owner.getDocument();
		if (self.inplace)
		{
			var prnt = elem.parentNode.parentNode;
			var pos = utils.getElementBox(prnt, doc);

			if (pos.width != 0)
				style.width = pos.width - corr - 4;
		}
		else
		if (!self.rect.isRelative())
		{
			style.width = self.rect.width - corr;
		}
	}

	function bind_setValue(prop, field, record)
	{
		if (self.$$() == null)
			return;

		if ((record) && (record.isNoData(field)))
			record = null;

		checkControlState(record);

		if ((record == null) || (record.dataset == null))
		{
			self.$$().value = '';
			self.value = null;
		}
		else
		{
//			if (utils.coalesce(self.value, "") == record.dataset.get(self.field))
//				return;

			self.$$().value = record.dataset.getText(self.field);
			self.value = record.dataset.get(self.field);
		}

		if (self.value != null)
			self.select(self.value);
	}


	function save()
	{
		if ((self.field.startsWith('__')) || (self.dataset.getRecNo() == null))
			return;

		var record = self.dataset.getCurrentRecord();
		if ((record) && ((record.isNoData(self.field)) || (record.isReadOnly(self.field))))
			return;
		
		if (self.value == '')
			self.value = null;

		self.dataset.set(self.field, self.value);

		if (self.value != self.orgValue)
			self.dirty = true;
		else
			self.dirty = false;
	}

	function select(item)
	{
		if (self.$$() == null)
			return;

		if (!self.isReadOnly(self.dataset, self.field))
		{
			self.dataset.fields[self.field].items.forIn( function(fldItem, i)
			{
				var itm = self.$$("_item_" + i);
				itm.style.backgroundColor = (item == i ? "highlight" : "");
				itm.style.color           = (item == i ? "window" : "windowtext");
			}, self);
	
			self.value = item;
			self.save();
			if ((_form != null) && (_form.checkSaveButton))
				_form.checkSaveButton(self);

			if (self.field.startsWith('__'))
				self.$$().value = utils.coalesce(self.dataset.fields[self.field].items[self.value], "");
			else
				self.$$().value = self.dataset.getText(self.field);

			if (self.rolled())
				self.roll();

			self.onchange.raise(self, item);
		}
		else
		{
			if (self.rolled())
				self.roll();
		}
	}
	
	function keyHandler(event)
	{
		if (!event)
			event = window.event;

		if ((!event.ctrlKey && utils.inList(event.keyCode, 8, 46)) && (! self.isReadOnly(self.dataset, self.field))) // BS, Del
		{
			self.value = null;
			self.save();
		}

		if ((!event.ctrlKey && utils.inList(event.keyCode, 9, 35, 36, 37, 39)) || (event.ctrlKey && utils.inList(event.keyCode, 67, 86)))
		{
			if (browser.isIE)
				event.returnValue = true;
		}
		else
		{
			if (browser.isIE)
				event.returnValue = false;
			else
				event.preventDefault();
		}
	}

	function _refreshPickerItems(fs)
	{
		fs.append('<table width="100%" id="' + self.name + '_list">');

		_itemsCount = 0;
		self.dataset.fields[self.field].items.forIn(function (item, name)
		{
			fs.append('<tr><td class="picker_item" width="100%" id="' + self.name + '_item_' + name + '" _itemId="' + name + '">' + item + "</td></tr>");
			_itemsCount++;
		}, self);

		fs.append("</table>");
	}

	function refreshPicker()
	{
		var picker = self.$$('_picker');
		if (picker)
		{
			var fs = new FastString();

			_disposeItems();
			_refreshPickerItems(fs);
			picker.innerHTML = fs.toString();
			_setClickHandlers();
		}
	}

	function _setClickHandlers()
	{
		var items = self.$$('_list').getElementsByTagName('td');
		for (var i = 0; i < items.length; i++)
		{
			var id = items[i].getAttribute('_itemId');
			items[i].onclick = getClickFunc(id);
		}
	} 

	function isRolled()
	{
		return utils.getStyle(self.$$("_picker"), 'display') != 'none';
	}

	function roll(event)
	{
		self.onrolling.raise(self, !self.rolled());

		var elem = self.$$();
		var picker = self.$$("_picker");
		if ((!elem) || (! picker))
			return;

		var style = picker.style;

		if (!self.rolled())
		{
			if (_itemsCount == 0)
				return;

			if ((self.canRollQuery != null) && (! self.canRollQuery()))
				return;  

			if (event == null)
				event = self.owner.getWindow().event;
			self.owner.registerPopup(picker.id, true, event);

			var doc = self.owner.getDocument();
			var pos = utils.getElementPosition(self.name, doc);

			var border = parseInt(utils.getStyle(elem, 'borderLeftWidth'));
			var borderTop = parseInt(utils.getStyle(elem, 'borderTopWidth'));
			if (isNaN(border))
				border = 0;
			if (isNaN(borderTop))
				borderTop = 0;

			var left = pos.left + border;
			var top = pos.top + elem.clientHeight + borderTop + 2;

/*
			var height = elem.clientHeight;
			if (top + height > doc.body.clientHeight - 15)
			{
				top = doc.body.clientHeight - height - 15;
				left = utils.getElementPosition(self.name + '_img', doc).left - picker.offsetWidth;
			}
			else
			{
				top = pos.top + elem.offsetHeight + border;
			}
*/


			style.left = left;
			style.width = elem.offsetWidth + 17;

			style.zIndex  = utils.getParentZIndex(self.$$()) + 1000;
			style.display = 'block';

			var height = picker.offsetHeight;
			if (height > 95)
			{
				height = 95;
				style.height = height;
			}

			if (top + height > doc.body.clientHeight - 2)
				top = pos.top - border - height;

			if (style.top = top)
				style.top = top;

			self.$$("_list").style.backgroundColor = (self.isReadOnly(self.dataset, self.field) == false) ? "" : "gainsboro";
			if (self.$$('_item_' + self.value) != null)
				self.$$('_item_' + self.value).scrollIntoView();

			return false;
		}
		else
		{
			picker.className = 'picker';
			//	    style.zIndex  = 0;
			style.display = 'none';
		}
	}

	function dispose()
	{
		if (_disposed)
		  return;

		if ((dataset != null) && (dataset.bindingManager != null))
			dataset.bindingManager.unbind(self);

		var elem = self.$$();
		var img = self.$$('_img');

		if (elem != null)
			elem.onkeydown = null;
		if (img != null)
		  img.onclick = null;

		if (self.onchange != null)
			self.onchange.dispose();

		_disposeItems();

		if (self.rolled())
			self.roll();

		var picker = self.$$("_picker");
		if (picker != null)
		{
			picker.style.display = 'none';
			if (picker.parentNode != null)
				picker.parentNode.removeChild(picker);
		}

		self.base.dispose.call(self);
		_disposed = true;
	}

	function _disposeItems()
	{
		if (self.$$('_list') == null)
		  return;

		var items = self.$$('_list').getElementsByTagName('td');
		for (var i = 0; i < items.length; i++)
		{
			items[i].onclick = null;
		}
	}
}

JEnumPicker.inheritsFrom(ControlBase);

if (typeof(loadNextScript) != 'undefined')
	loadNextScript();